/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package blink.view.task;


import blink.guimodel.TargetListModel;
import blink.model.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.Box.Filler;
import javax.swing.event.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.Document;

/**
 * Panel d'édition d'une tache.
 *
 * @author jerome
 */
public class TaskPanel extends javax.swing.JPanel {

    private Task task;
    private Target currentTarget;
    private GenericListModel targetStimuliModel = new GenericListModel<Stimulus>();
    private GenericListModel fillerModel = new GenericListModel<Stimulus>();
    private TargetListModel targetModel;
    private ListCellRenderer imageListCellRenderer = new StimulusListCellRenderer();
    ListSelectionListener internalLSL = new ListSelectionListener() {

        @Override
        public void valueChanged(ListSelectionEvent lse) {
            if (lse.getSource() == listFillers) {
                btRemFiller.setEnabled(listFillers.getSelectedIndex() > -1);
            } else if (lse.getSource() == listTargets && !lse.getValueIsAdjusting()) {
                if (listTargets.getSelectedIndex() > -1) {
                    btRemTarget.setEnabled(true);
                    if (currentTarget != null && majCurrentTarget()) {
                        listTargets.setSelectedValue(currentTarget, true);
                        return;
                    }

                    //epQuestion.
                    setCurrentTarget((Target) listTargets.getSelectedValue());

                } else {
                    btRemTarget.setEnabled(false);
                    setCurrentTarget(null);

                }
            } else if (lse.getSource() == listTargetsSti) {
                btRemTargetStimulus.setEnabled(listTargetsSti.getSelectedIndex() > -1);
            }
        }
    };

    private boolean majCurrentTarget() {
        boolean maj = false;
        if (!epQuestion.getText().equals(currentTarget.getQuestion())) {
            currentTarget.setQuestion(epQuestion.getText());
            maj = true;
        }
        if (!tfTargetName.getText().equals(currentTarget.getName())) {
            currentTarget.setName(tfTargetName.getText());
            maj = true;
        }
        currentTarget.setPossiblePositions((int[]) tfTargetPositions.getValue());
        return maj;
    }

    /**
     * Creates new form TaskDialog
     */
    public TaskPanel(Task t) {
        task = t;
        initComponents();
        setModel(t);
        btRemFiller.setEnabled(listFillers.getSelectedIndex() > -1);
        setCurrentTarget(null);

    }

    public final void setModel(Task t) {
        this.task = t;
        fillerModel = new GenericListModel(task.getFillers());
        listFillers.setModel(fillerModel);

        targetModel = new TargetListModel(task);
        listTargets.setModel(targetModel);

        tfTaskName.setText(task.getName());
        spinnerDisplayTime.setValue(task.getDisplayTime());
        spinnerLagTime.setValue(task.getLagTime());
        tfSeqLengths.setValue(task.getPossibleSequenceLengths());
        jSpinner1.setValue(((double) task.getStimulusSize())/10);

    }

    public Task getModel() {
        return task;
    }

    private void setCurrentTarget(Target target) {
        currentTarget = target;
        if (currentTarget == null) {
            tfTargetName.setText("");//java.util.ResourceBundle.getBundle("blink/view/task/TaskBundle").getString("TaskPanel.tfTargetName.name")+task.getTargets().size());
            spinnerTargetProba.setValue(0.0);
            comboTargetType.setSelectedIndex(0);
            targetStimuliModel.setList(Collections.emptyList());
            tfTargetPositions.setValue(null);
            epQuestion.setText("");

        } else {
            tfTargetName.setText(currentTarget.getName());
            spinnerTargetProba.setValue(currentTarget.getProbability());
            comboTargetType.setSelectedIndex(currentTarget.isDetected() ? 0 : 1);
            targetStimuliModel.setList(currentTarget.getPossibleTargets());
            tfTargetPositions.setValue(currentTarget.getPossiblePositions());
            epQuestion.setText(currentTarget.getQuestion());
        }
        enableAllContainedComp(panelTargetInfos);

    }

    private void enableAllContainedComp(Container container) {
        for (Component c : container.getComponents()) {
            if (c instanceof Container && ((Container) c).getComponentCount() > 0) {
                enableAllContainedComp(((Container) c));
            }
            c.setEnabled(currentTarget != null);
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        GridBagConstraints gridBagConstraints; 

        fillerChooser = new JFileChooser();
        errorSeqLengthEmpty = new JOptionPane();
        jtpTask = new JTabbedPane();
        jpTask = new JPanel();
        lblTaskName = new JLabel();
        tfTaskName = new JTextField();
        lblDisplayTime = new JLabel();
        spinnerDisplayTime = new JSpinner();
        lblLagTime = new JLabel();
        spinnerLagTime = new JSpinner();
        lblSequenceLengths = new JLabel();
        tfSeqLengths = new JFormattedTextField();
        lblFillers = new JLabel();
        jpFillers = new JPanel();
        jScrollPane2 = new JScrollPane();
        listFillers = new JList();
        btAddFiller = new JButton();
        btRemFiller = new JButton();
        lblScreenSize = new JLabel();
        jSpinner1 = new JSpinner();
        jpTargets = new JPanel();
        panelTargetInfos = new JPanel();
        lblTargetProbability = new JLabel();
        lblTargetPossiblePositions = new JLabel();
        lblTargetType = new JLabel();
        tfTargetPositions = new JFormattedTextField();
        lblTargetName = new JLabel();
        tfTargetName = new JTextField();
        btAddTargetStimulus = new JButton();
        btRemTargetStimulus = new JButton();
        jScrollPane3 = new JScrollPane();
        listTargetsSti = new JList();
        comboTargetType = new JComboBox();
        lblTargetStimuli = new JLabel();
        spinnerTargetProba = new JSpinner();
        lblTargetQuestion = new JLabel();
        spQuestion = new JScrollPane();
        epQuestion = new JEditorPane();
        btAddTarget = new JButton();
        btRemTarget = new JButton();
        spTargetList = new JScrollPane();
        listTargets = new JList();
        btSaveTask = new JButton();
        btRemoveTask = new JButton();
        Filler filler = new Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(32767, 32767));
        FormListener formListener = new FormListener();

        fillerChooser.setFileFilter(new FileNameExtensionFilter("JPG & GIF Images", "jpg", "gif"));
        ResourceBundle bundle = ResourceBundle.getBundle("blink/view/task/TaskBundle"); // NOI18N
        fillerChooser.setName(bundle.getString("TaskPanel.fillerChooser.name")); // NOI18N

        errorSeqLengthEmpty.setName(bundle.getString("TaskPanel.errorSeqLengthEmpty.name")); // NOI18N

        setBackground(Color.white);
        setName(bundle.getString("TaskPanel.name")); // NOI18N
        setLayout(new GridBagLayout());

        jtpTask.setName(bundle.getString("TaskPanel.jtpTask.name")); // NOI18N

        jpTask.setName(bundle.getString("TaskPanel.jpTask.name")); // NOI18N
        jpTask.setLayout(new GridBagLayout());

        lblTaskName.setText(bundle.getString("TaskPanel.lblTaskName.text")); // NOI18N
        lblTaskName.setName(bundle.getString("TaskPanel.lblTaskName.name")); // NOI18N
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = GridBagConstraints.LINE_END;
        jpTask.add(lblTaskName, gridBagConstraints);

        tfTaskName.setColumns(20);
        tfTaskName.setText(bundle.getString("TaskPanel.tfTaskName.text")); // NOI18N
        tfTaskName.setMinimumSize(tfTaskName.getPreferredSize());
        tfTaskName.setName(bundle.getString("TaskPanel.tfTaskName.name")); // NOI18N
        tfTaskName.addFocusListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.1;
        jpTask.add(tfTaskName, gridBagConstraints);

        lblDisplayTime.setText(bundle.getString("TaskPanel.lblDisplayTime.text")); // NOI18N
        lblDisplayTime.setName(bundle.getString("TaskPanel.lblDisplayTime.name")); // NOI18N
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = GridBagConstraints.LINE_END;
        jpTask.add(lblDisplayTime, gridBagConstraints);

        spinnerDisplayTime.setModel(new SpinnerNumberModel(Integer.valueOf(1), Integer.valueOf(1), null, Integer.valueOf(1)));
        spinnerDisplayTime.setMinimumSize(new Dimension(70, 28));
        spinnerDisplayTime.setName(bundle.getString("TaskPanel.spinnerDisplayTime.name")); // NOI18N
        spinnerDisplayTime.setPreferredSize(new Dimension(70, 28));
        spinnerDisplayTime.addFocusListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.1;
        jpTask.add(spinnerDisplayTime, gridBagConstraints);

        lblLagTime.setText(bundle.getString("TaskPanel.lblLagTime.text")); // NOI18N
        lblLagTime.setName(bundle.getString("TaskPanel.lblLagTime.name")); // NOI18N
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = GridBagConstraints.LINE_END;
        jpTask.add(lblLagTime, gridBagConstraints);

        spinnerLagTime.setModel(new SpinnerNumberModel());
        spinnerLagTime.setMinimumSize(new Dimension(70, 28));
        spinnerLagTime.setName(bundle.getString("TaskPanel.spinnerLagTime.name")); // NOI18N
        spinnerLagTime.setPreferredSize(new Dimension(70, 28));
        spinnerLagTime.addFocusListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.1;
        jpTask.add(spinnerLagTime, gridBagConstraints);

        lblSequenceLengths.setText(bundle.getString("TaskPanel.lblSequenceLengths.text")); // NOI18N
        lblSequenceLengths.setName(bundle.getString("TaskPanel.lblSequenceLengths.name")); // NOI18N
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = GridBagConstraints.LINE_END;
        jpTask.add(lblSequenceLengths, gridBagConstraints);

        tfSeqLengths.setColumns(20);
        tfSeqLengths.setFormatterFactory(new DefaultFormatterFactory(new IntArrayFormat()));
        tfSeqLengths.setText(bundle.getString("TaskPanel.tfSeqLengths.text")); // NOI18N
        tfSeqLengths.setMinimumSize(tfSeqLengths.getPreferredSize());
        tfSeqLengths.setName(bundle.getString("TaskPanel.tfSeqLengths.name")); // NOI18N
        tfSeqLengths.addPropertyChangeListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.1;
        jpTask.add(tfSeqLengths, gridBagConstraints);

        lblFillers.setText(bundle.getString("TaskPanel.lblFillers.text")); // NOI18N
        lblFillers.setName(bundle.getString("TaskPanel.lblFillers.name")); // NOI18N
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.anchor = GridBagConstraints.FIRST_LINE_END;
        jpTask.add(lblFillers, gridBagConstraints);

        jpFillers.setName(bundle.getString("TaskPanel.jpFillers.name")); // NOI18N
        jpFillers.setLayout(new GridBagLayout());

        jScrollPane2.setName(bundle.getString("TaskPanel.jScrollPane2.name")); // NOI18N
        jScrollPane2.setPreferredSize(new Dimension(154, 504));

        listFillers.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        listFillers.setCellRenderer(imageListCellRenderer);
        listFillers.setFixedCellHeight(100);
        listFillers.setFixedCellWidth(150);
        listFillers.setLayoutOrientation(JList.HORIZONTAL_WRAP);
        listFillers.setName(bundle.getString("TaskPanel.listFillers.name")); // NOI18N
        listFillers.setVisibleRowCount(-1);
        listFillers.addListSelectionListener(internalLSL);
        jScrollPane2.setViewportView(listFillers);

        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.2;
        jpFillers.add(jScrollPane2, gridBagConstraints);

        btAddFiller.setText(bundle.getString("TaskPanel.btAddFiller.text")); // NOI18N
        btAddFiller.setIconTextGap(0);
        btAddFiller.setMinimumSize(new Dimension(40, 29));
        btAddFiller.setName(bundle.getString("TaskPanel.btAddFiller.name")); // NOI18N
        btAddFiller.setPreferredSize(new Dimension(40, 29));
        btAddFiller.addActionListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.fill = GridBagConstraints.VERTICAL;
        gridBagConstraints.weighty = 0.1;
        jpFillers.add(btAddFiller, gridBagConstraints);

        btRemFiller.setText(bundle.getString("TaskPanel.btRemFiller.text")); // NOI18N
        btRemFiller.setMinimumSize(new Dimension(40, 29));
        btRemFiller.setName(bundle.getString("TaskPanel.btRemFiller.name")); // NOI18N
        btRemFiller.setPreferredSize(new Dimension(40, 29));
        btRemFiller.addActionListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = GridBagConstraints.VERTICAL;
        gridBagConstraints.weighty = 0.1;
        jpFillers.add(btRemFiller, gridBagConstraints);

        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.1;
        jpTask.add(jpFillers, gridBagConstraints);

        lblScreenSize.setText(bundle.getString("TaskPanel.lblScreenSize.text")); // NOI18N
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = GridBagConstraints.LINE_END;
        jpTask.add(lblScreenSize, gridBagConstraints);

        jSpinner1.setModel(new SpinnerNumberModel(Double.valueOf(5.0d), Double.valueOf(0.0d), null, Double.valueOf(0.1d)));
        jSpinner1.setMinimumSize(new Dimension(70, 28));
        jSpinner1.addChangeListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.1;
        jpTask.add(jSpinner1, gridBagConstraints);

        jtpTask.addTab(bundle.getString("TaskPanel.jpTask.TabConstraints.tabTitle"), jpTask); // NOI18N

        jpTargets.setName(bundle.getString("TaskPanel.jpTargets.name")); // NOI18N
        jpTargets.setLayout(new GridBagLayout());

        panelTargetInfos.setBorder(BorderFactory.createTitledBorder(bundle.getString("TaskPanel.panelTargetInfos.border.title")));         panelTargetInfos.setName(bundle.getString("TaskPanel.panelTargetInfos.name")); // NOI18N
        panelTargetInfos.setLayout(new GridBagLayout());

        lblTargetProbability.setText(bundle.getString("TaskPanel.lblTargetProbability.text")); // NOI18N
        lblTargetProbability.setName(bundle.getString("TaskPanel.lblTargetProbability.name")); // NOI18N
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = GridBagConstraints.LINE_END;
        panelTargetInfos.add(lblTargetProbability, gridBagConstraints);

        lblTargetPossiblePositions.setText(bundle.getString("TaskPanel.lblTargetPossiblePositions.text")); // NOI18N
        lblTargetPossiblePositions.setName(bundle.getString("TaskPanel.lblTargetPossiblePositions.name")); // NOI18N
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = GridBagConstraints.LINE_END;
        panelTargetInfos.add(lblTargetPossiblePositions, gridBagConstraints);

        lblTargetType.setText(bundle.getString("TaskPanel.lblTargetType.text")); // NOI18N
        lblTargetType.setName(bundle.getString("TaskPanel.lblTargetType.name")); // NOI18N
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = GridBagConstraints.LINE_END;
        panelTargetInfos.add(lblTargetType, gridBagConstraints);

        tfTargetPositions.setColumns(15);
        tfTargetPositions.setFormatterFactory(new DefaultFormatterFactory(new IntArrayFormat()));
        tfTargetPositions.setText(bundle.getString("TaskPanel.tfTargetPositions.text")); // NOI18N
        tfTargetPositions.setMinimumSize(tfTargetPositions.getPreferredSize());
        tfTargetPositions.setName(bundle.getString("TaskPanel.tfTargetPositions.name")); // NOI18N
        tfTargetPositions.addPropertyChangeListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = GridBagConstraints.WEST;
        gridBagConstraints.weightx = 0.1;
        panelTargetInfos.add(tfTargetPositions, gridBagConstraints);

        lblTargetName.setText(bundle.getString("TaskPanel.lblTargetName.text")); // NOI18N
        lblTargetName.setName(bundle.getString("TaskPanel.lblTargetName.name")); // NOI18N
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.anchor = GridBagConstraints.LINE_END;
        panelTargetInfos.add(lblTargetName, gridBagConstraints);

        tfTargetName.setColumns(15);
        tfTargetName.setMinimumSize(tfTargetName.getPreferredSize());
        tfTargetName.setName(bundle.getString("TaskPanel.tfTargetName.name")); // NOI18N
        tfTargetName.addFocusListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.1;
        panelTargetInfos.add(tfTargetName, gridBagConstraints);

        btAddTargetStimulus.setText(bundle.getString("TaskPanel.btAddTargetStimulus.text")); // NOI18N
        btAddTargetStimulus.setAlignmentX(0.5F);
        btAddTargetStimulus.setHorizontalTextPosition(SwingConstants.CENTER);
        btAddTargetStimulus.setIconTextGap(0);
        btAddTargetStimulus.setMargin(new Insets(0, 0, 0, 0));
        btAddTargetStimulus.setName(bundle.getString("TaskPanel.btAddTargetStimulus.name")); // NOI18N
        btAddTargetStimulus.setRequestFocusEnabled(false);
        btAddTargetStimulus.addActionListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.fill = GridBagConstraints.VERTICAL;
        gridBagConstraints.weighty = 0.1;
        gridBagConstraints.insets = new Insets(10, 0, 0, 0);
        panelTargetInfos.add(btAddTargetStimulus, gridBagConstraints);

        btRemTargetStimulus.setText(bundle.getString("TaskPanel.btRemTargetStimulus.text")); // NOI18N
        btRemTargetStimulus.setName(bundle.getString("TaskPanel.btRemTargetStimulus.name")); // NOI18N
        btRemTargetStimulus.addActionListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 6;
        gridBagConstraints.fill = GridBagConstraints.VERTICAL;
        gridBagConstraints.weighty = 0.1;
        gridBagConstraints.insets = new Insets(0, 0, 10, 0);
        panelTargetInfos.add(btRemTargetStimulus, gridBagConstraints);

        jScrollPane3.setName(bundle.getString("TaskPanel.jScrollPane3.name")); // NOI18N

        listTargetsSti.setModel(targetStimuliModel);
        listTargetsSti.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        listTargetsSti.setCellRenderer(imageListCellRenderer);
        listTargetsSti.setLayoutOrientation(JList.HORIZONTAL_WRAP);
        listTargetsSti.setName(bundle.getString("TaskPanel.listTargetsSti.name")); // NOI18N
        listTargetsSti.setVerifyInputWhenFocusTarget(false);
        listTargetsSti.setVisibleRowCount(-1);
        jScrollPane3.setViewportView(listTargetsSti);

        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.weighty = 0.2;
        gridBagConstraints.insets = new Insets(10, 0, 10, 0);
        panelTargetInfos.add(jScrollPane3, gridBagConstraints);

        comboTargetType.setModel(new DefaultComboBoxModel(new String[] { "Detected", "Identified" }));
        comboTargetType.setName(bundle.getString("TaskPanel.comboTargetType.name")); // NOI18N
        comboTargetType.addActionListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.1;
        panelTargetInfos.add(comboTargetType, gridBagConstraints);

        lblTargetStimuli.setText(bundle.getString("TaskPanel.lblTargetStimuli.text")); // NOI18N
        lblTargetStimuli.setName(bundle.getString("TaskPanel.lblTargetStimuli.name")); // NOI18N
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        panelTargetInfos.add(lblTargetStimuli, gridBagConstraints);

        spinnerTargetProba.setModel(new SpinnerNumberModel(1.0d, 0.0d, 1.0d, 0.1d));
        spinnerTargetProba.setMinimumSize(new Dimension(61, 28));
        spinnerTargetProba.setName(bundle.getString("TaskPanel.spinnerTargetProba.name")); // NOI18N
        spinnerTargetProba.setPreferredSize(new Dimension(61, 28));
        spinnerTargetProba.addChangeListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 0.1;
        panelTargetInfos.add(spinnerTargetProba, gridBagConstraints);

        lblTargetQuestion.setText(bundle.getString("TaskPanel.lblTargetQuestion.text")); // NOI18N
        lblTargetQuestion.setName(bundle.getString("TaskPanel.lblTargetQuestion.name")); // NOI18N
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.anchor = GridBagConstraints.LINE_START;
        panelTargetInfos.add(lblTargetQuestion, gridBagConstraints);

        spQuestion.setName(bundle.getString("TaskPanel.spQuestion.name")); // NOI18N

        epQuestion.setName(bundle.getString("TaskPanel.epQuestion.name")); // NOI18N
        epQuestion.addFocusListener(formListener);
        spQuestion.setViewportView(epQuestion);

        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.5;
        panelTargetInfos.add(spQuestion, gridBagConstraints);

        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 2.0;
        gridBagConstraints.weighty = 0.1;
        jpTargets.add(panelTargetInfos, gridBagConstraints);

        btAddTarget.setText(bundle.getString("TaskPanel.btAddTarget.text")); // NOI18N
        btAddTarget.setName(bundle.getString("TaskPanel.btAddTarget.name")); // NOI18N
        btAddTarget.addActionListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 0.1;
        jpTargets.add(btAddTarget, gridBagConstraints);

        btRemTarget.setText(bundle.getString("TaskPanel.btRemTarget.text")); // NOI18N
        btRemTarget.setName(bundle.getString("TaskPanel.btRemTarget.name")); // NOI18N
        btRemTarget.addActionListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 0.1;
        jpTargets.add(btRemTarget, gridBagConstraints);

        spTargetList.setMinimumSize(tfTargetName.getPreferredSize());
        spTargetList.setName(bundle.getString("TaskPanel.spTargetList.name")); // NOI18N
        spTargetList.setPreferredSize(tfTargetName.getPreferredSize());

        listTargets.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        listTargets.setName(bundle.getString("TaskPanel.listTargets.name")); // NOI18N
        listTargets.addListSelectionListener(internalLSL);
        spTargetList.setViewportView(listTargets);

        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.weighty = 0.1;
        jpTargets.add(spTargetList, gridBagConstraints);

        jtpTask.addTab(bundle.getString("TaskPanel.jpTargets.TabConstraints.tabTitle"), jpTargets); // NOI18N

        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.weighty = 0.1;
        add(jtpTask, gridBagConstraints);

        btSaveTask.setText(bundle.getString("TaskPanel.btSaveTask.text")); // NOI18N
        btSaveTask.setName(bundle.getString("TaskPanel.btSaveTask.name")); // NOI18N
        btSaveTask.addActionListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        add(btSaveTask, gridBagConstraints);

        btRemoveTask.setText(bundle.getString("TaskPanel.btRemoveTask.text")); // NOI18N
        btRemoveTask.setName(bundle.getString("TaskPanel.btRemoveTask.name")); // NOI18N
        btRemoveTask.addActionListener(formListener);
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = GridBagConstraints.LINE_END;
        add(btRemoveTask, gridBagConstraints);

        filler.setName(bundle.getString("TaskPanel.filler.name")); // NOI18N
        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        add(filler, gridBagConstraints);
    }

    // Code for dispatching events from components to event handlers.

    private class FormListener implements ActionListener, FocusListener, PropertyChangeListener, ChangeListener {
        FormListener() {}
        public void actionPerformed(ActionEvent evt) {
            if (evt.getSource() == btAddFiller) {
                TaskPanel.this.btAddFillerActionPerformed(evt);
            }
            else if (evt.getSource() == btRemFiller) {
                TaskPanel.this.btRemFillerActionPerformed(evt);
            }
            else if (evt.getSource() == btAddTargetStimulus) {
                TaskPanel.this.btAddTargetStimulusActionPerformed(evt);
            }
            else if (evt.getSource() == btRemTargetStimulus) {
                TaskPanel.this.btRemTargetStimulusActionPerformed(evt);
            }
            else if (evt.getSource() == comboTargetType) {
                TaskPanel.this.comboTargetTypeActionPerformed(evt);
            }
            else if (evt.getSource() == btAddTarget) {
                TaskPanel.this.btAddTargetActionPerformed(evt);
            }
            else if (evt.getSource() == btRemTarget) {
                TaskPanel.this.btRemTargetActionPerformed(evt);
            }
            else if (evt.getSource() == btSaveTask) {
                TaskPanel.this.btSaveTaskActionPerformed(evt);
            }
            else if (evt.getSource() == btRemoveTask) {
                TaskPanel.this.btRemoveTaskActionPerformed(evt);
            }
        }

        public void focusGained(FocusEvent evt) {
        }

        public void focusLost(FocusEvent evt) {
            if (evt.getSource() == tfTaskName) {
                TaskPanel.this.tfTaskNameFocusLost(evt);
            }
            else if (evt.getSource() == spinnerDisplayTime) {
                TaskPanel.this.spinnerDisplayTimeFocusLost(evt);
            }
            else if (evt.getSource() == spinnerLagTime) {
                TaskPanel.this.spinnerLagTimeFocusLost(evt);
            }
            else if (evt.getSource() == tfTargetName) {
                TaskPanel.this.tfTargetNameFocusLost(evt);
            }
            else if (evt.getSource() == epQuestion) {
                TaskPanel.this.epQuestionFocusLost(evt);
            }
        }

        public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getSource() == tfSeqLengths) {
                TaskPanel.this.tfSeqLengthsPropertyChange(evt);
            }
            else if (evt.getSource() == tfTargetPositions) {
                TaskPanel.this.tfTargetPositionsPropertyChange(evt);
            }
        }

        public void stateChanged(ChangeEvent evt) {
            if (evt.getSource() == jSpinner1) {
                TaskPanel.this.jSpinner1StateChanged(evt);
            }
            else if (evt.getSource() == spinnerTargetProba) {
                TaskPanel.this.spinnerTargetProbaStateChanged(evt);
            }
        }
    }// </editor-fold>//GEN-END:initComponents

    /*
     * private void checkErrors() { boolean error = false; if
     * (task.getFillers().isEmpty()) { JOptionPane.showMessageDialog(this, "The
     * task should contains at least one filler", "",
     * JOptionPane.ERROR_MESSAGE); error = true; } if
     * (task.getTargets().isEmpty()) { jtpTask.setSelectedComponent(jpTargets);
     * JOptionPane.showMessageDialog(this, "The task should contains at least
     * one target", "", JOptionPane.ERROR_MESSAGE); error = true; } if (error) {
     * throw new RuntimeException(); }
    }
     */
    public Task validateChanges() {
        
        task.setName(tfTaskName.getText());
        task.setDisplayTime((Integer) this.spinnerDisplayTime.getValue());
        task.setLagTime((Integer) this.spinnerLagTime.getValue());
        task.setPossibleSequenceLengths((int[]) tfSeqLengths.getValue());
        
        
        System.out.println("toto" + task.getName());
        
        
        if (task.getFillers().isEmpty()) {
            throw new RuntimeException("The task must contain at least one filler");
        }
        if (task.getTargets().isEmpty()) {
            throw new RuntimeException("The task must contain at least one target");

        }

        return task;
    }

    private void btSaveTaskActionPerformed(ActionEvent evt) {//GEN-FIRST:event_btSaveTaskActionPerformed
        
        validateChanges();
        this.fireSaveAction(evt);
    }//GEN-LAST:event_btSaveTaskActionPerformed

    private void btAddTargetActionPerformed(ActionEvent evt) {//GEN-FIRST:event_btAddTargetActionPerformed
        targetModel.createNewTarget();

    }//GEN-LAST:event_btAddTargetActionPerformed

    private void btAddFillerActionPerformed(ActionEvent evt) {//GEN-FIRST:event_btAddFillerActionPerformed
        int returnVal = fillerChooser.showOpenDialog(TaskPanel.this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File choosenFile = fillerChooser.getSelectedFile();
            try {
                Stimulus f = new Stimulus(choosenFile);

                fillerModel.add(f);

            } catch (IOException ex) {
                Logger.getLogger(TaskPanel.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
    }//GEN-LAST:event_btAddFillerActionPerformed

    private void btRemFillerActionPerformed(ActionEvent evt) {//GEN-FIRST:event_btRemFillerActionPerformed
        fillerModel.remove(listFillers.getSelectedIndex());
    }//GEN-LAST:event_btRemFillerActionPerformed

    private void tfTaskNameFocusLost(FocusEvent evt) {//GEN-FIRST:event_tfTaskNameFocusLost
        try {
            task.setName(tfTaskName.getText());
        } catch (Exception e) {
            showError(e);
            tfTaskName.setText(task.getName());
        }
    }//GEN-LAST:event_tfTaskNameFocusLost

    private void spinnerDisplayTimeFocusLost(FocusEvent evt) {//GEN-FIRST:event_spinnerDisplayTimeFocusLost
        task.setDisplayTime((Integer) spinnerDisplayTime.getValue());
    }//GEN-LAST:event_spinnerDisplayTimeFocusLost

    private void spinnerLagTimeFocusLost(FocusEvent evt) {//GEN-FIRST:event_spinnerLagTimeFocusLost
        task.setLagTime((Integer) spinnerLagTime.getValue());
    }//GEN-LAST:event_spinnerLagTimeFocusLost

    private void btRemTargetActionPerformed(ActionEvent evt) {//GEN-FIRST:event_btRemTargetActionPerformed
        targetModel.remove(listTargets.getSelectedIndex());
    }//GEN-LAST:event_btRemTargetActionPerformed

    private void tfTargetNameFocusLost(FocusEvent evt) {//GEN-FIRST:event_tfTargetNameFocusLost
        if (currentTarget != null) {
            try {
                currentTarget.setName(tfTargetName.getText());
                targetModel.fireContentsChanged(listTargets.getSelectedIndex());
            } catch (Exception e) {
                showError(e);
                tfTargetName.setText(currentTarget.getName());
            }
        }

    }//GEN-LAST:event_tfTargetNameFocusLost

    private void spinnerTargetProbaStateChanged(ChangeEvent evt) {//GEN-FIRST:event_spinnerTargetProbaStateChanged
        if (currentTarget != null) {
            currentTarget.setProbability((Double) spinnerTargetProba.getValue());
        }
        //System.out.println(currentTarget.getProbability());
    }//GEN-LAST:event_spinnerTargetProbaStateChanged

    private void comboTargetTypeActionPerformed(ActionEvent evt) {//GEN-FIRST:event_comboTargetTypeActionPerformed
        if (currentTarget != null) {
            currentTarget.setDetected(comboTargetType.getSelectedIndex() == 0);
        }

    }//GEN-LAST:event_comboTargetTypeActionPerformed

    private void btAddTargetStimulusActionPerformed(ActionEvent evt) {//GEN-FIRST:event_btAddTargetStimulusActionPerformed
        int returnVal = fillerChooser.showOpenDialog(TaskPanel.this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File choosenFile = fillerChooser.getSelectedFile();
            try {
                Stimulus f = new Stimulus(choosenFile); //NOI18N
                targetStimuliModel.add(f);

            } catch (IOException ex) {
                Logger.getLogger(TaskPanel.class.getName()).log(Level.SEVERE, null, ex);
            }

        }

    }//GEN-LAST:event_btAddTargetStimulusActionPerformed

    private void btRemTargetStimulusActionPerformed(ActionEvent evt) {//GEN-FIRST:event_btRemTargetStimulusActionPerformed
        targetStimuliModel.remove(this.listTargetsSti.getSelectedIndex());
    }//GEN-LAST:event_btRemTargetStimulusActionPerformed

    private void tfTargetPositionsPropertyChange(PropertyChangeEvent evt) {//GEN-FIRST:event_tfTargetPositionsPropertyChange
        if (currentTarget != null) {
            try {
                currentTarget.setPossiblePositions((int[]) tfTargetPositions.getValue());
            } catch (Exception e) {
                showError(e);
                tfTargetPositions.setValue(currentTarget.getPossiblePositions());
            }
        }
    }//GEN-LAST:event_tfTargetPositionsPropertyChange

    private void btRemoveTaskActionPerformed(ActionEvent evt) {//GEN-FIRST:event_btRemoveTaskActionPerformed
        //this.setVisible(false);
        fireDeleteAction(evt);
    }//GEN-LAST:event_btRemoveTaskActionPerformed

    private void tfSeqLengthsPropertyChange(PropertyChangeEvent evt) {//GEN-FIRST:event_tfSeqLengthsPropertyChange
        int[] seqLengths = (int[]) tfSeqLengths.getValue();
        try {
            task.setPossibleSequenceLengths(seqLengths);
        } catch (Exception e) {
            showError(e);
            tfSeqLengths.setValue(task.getPossibleSequenceLengths());
        }

    }//GEN-LAST:event_tfSeqLengthsPropertyChange

    private void epQuestionFocusLost(FocusEvent evt) {//GEN-FIRST:event_epQuestionFocusLost
        try {
            currentTarget.setQuestion(epQuestion.getText());
        } catch (Exception e) {
            showError(e);
            epQuestion.setText(currentTarget.getQuestion());
        }
    }//GEN-LAST:event_epQuestionFocusLost

    private void jSpinner1StateChanged(ChangeEvent evt) {//GEN-FIRST:event_jSpinner1StateChanged
        if (task!=null)
            task.setStimulusSize((int) ((Double)jSpinner1.getValue()).doubleValue()*10);
    }//GEN-LAST:event_jSpinner1StateChanged

    protected java.util.List<TaskPanelListener> tpListeners = new ArrayList<TaskPanelListener>();
    
    public void addTaskPanelListener(TaskPanelListener tpl) {
        tpListeners.add(tpl);
    }

    public void removeTaskPanelListener(TaskPanelListener tpl) {
         tpListeners.remove(tpl);
    }
    
    protected void fireSaveAction(ActionEvent e) {
        e.setSource(this);
        for (TaskPanelListener l : tpListeners) l.saveActionPerformed(e);
    }
    
    protected void fireDeleteAction(ActionEvent e) {
        e.setSource(this);
        for (TaskPanelListener l : tpListeners) l.deleteActionPerformed(e);
    }

    private void showError(Exception e) {
        JOptionPane.showMessageDialog(this, e.getLocalizedMessage(), "", JOptionPane.ERROR_MESSAGE);
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private JButton btAddFiller;
    private JButton btAddTarget;
    private JButton btAddTargetStimulus;
    private JButton btRemFiller;
    private JButton btRemTarget;
    private JButton btRemTargetStimulus;
    private JButton btRemoveTask;
    private JButton btSaveTask;
    private JComboBox comboTargetType;
    private JEditorPane epQuestion;
    private JOptionPane errorSeqLengthEmpty;
    private JFileChooser fillerChooser;
    private JScrollPane jScrollPane2;
    private JScrollPane jScrollPane3;
    private JSpinner jSpinner1;
    private JPanel jpFillers;
    private JPanel jpTargets;
    private JPanel jpTask;
    private JTabbedPane jtpTask;
    private JLabel lblDisplayTime;
    private JLabel lblFillers;
    private JLabel lblLagTime;
    private JLabel lblScreenSize;
    private JLabel lblSequenceLengths;
    private JLabel lblTargetName;
    private JLabel lblTargetPossiblePositions;
    private JLabel lblTargetProbability;
    private JLabel lblTargetQuestion;
    private JLabel lblTargetStimuli;
    private JLabel lblTargetType;
    private JLabel lblTaskName;
    private JList listFillers;
    private JList listTargets;
    private JList listTargetsSti;
    private JPanel panelTargetInfos;
    private JScrollPane spQuestion;
    private JScrollPane spTargetList;
    private JSpinner spinnerDisplayTime;
    private JSpinner spinnerLagTime;
    private JSpinner spinnerTargetProba;
    private JFormattedTextField tfSeqLengths;
    private JTextField tfTargetName;
    private JFormattedTextField tfTargetPositions;
    private JTextField tfTaskName;
    // End of variables declaration//GEN-END:variables
}
